package com.demo.java.OD551_600.OD572;

import java.util.Scanner;
import java.util.*;

/**
 * @author bug菌
 * @Source 公众号：猿圈奇妙屋
 * @des： 【全排列(B卷-100分)】问题
 * @url： https://blog.csdn.net/weixin_43970743/article/details/146559334
 */
public class OdMain {
    public static void main(String[] args) {
        // 处理输入
        Scanner in = new Scanner(System.in);
        String input_str = in.nextLine();
        char[] char_array = input_str.toCharArray();
        // 先排序
        Arrays.sort(char_array);
        List<Character> path = new ArrayList<Character>();
        // 判断字符是否使用过
        boolean[] used = new boolean[char_array.length];
        List<List<Character>> res = new ArrayList<>();
        dfs(char_array, 0, path, used, res);
        System.out.println(res.size());  // 输出排列的个数
    }

    // 回溯法生成排列
    private static void dfs(char[] char_array, int depth, List<Character> path, boolean[] used, List<List<Character>> res) {
        if (depth == char_array.length) {  // 如果当前路径的长度等于字符数组的长度，说明已经找到一个排列
            res.add(new ArrayList<>(path));  // 将路径加入结果集
            return;
        }
        for (int i = 0; i < char_array.length; i++) {
            if (used[i]) {  // 如果字符已经使用过，跳过
                continue;
            }
            // 用过了就跳过，重复字符也跳过
            if (i > 0 && char_array[i] == char_array[i - 1] && !used[i - 1]) {
                continue;  // 如果当前字符和前一个字符相同且前一个字符还没使用过，则跳过
            }
            path.add(char_array[i]);
            used[i] = true;  // 标记当前字符已使用
            dfs(char_array, depth + 1, path, used, res);  // 递归调用
            path.remove(path.size() - 1);  // 回溯，移除最后一个字符
            used[i] = false;  // 恢复当前字符的使用状态
        }
    }
}